package com.txm.controller;


import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.txm.model.Bind.File;
import com.txm.model.hibernate.Hibernate;
import com.txm.model.hibernate.User;
import com.txm.model.mvc.Course;
import com.txm.service.TestService;
import common.model.AppResult;
import common.util.CSVUtil;
import common.webSocket.SystemWebSocketHandler;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.socket.TextMessage;

import javax.imageio.ImageIO;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.security.GeneralSecurityException;
import java.util.*;
import java.util.List;

/*import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;*/

/**
 * Created by Administrator on 2016/3/17.
 */


@Controller
@RequestMapping("test")
public class MVCController extends BaseController {
    private static HttpClient hc = HttpClients.createDefault();
    @Autowired
    private TestService testService;
    @Autowired
    private RedisTemplate<String, String> template;
    @Value("#{configProperties['aes']}")
    private String aes;

    public MVCController() throws IOException {
    }

    public static void main(String[] args) throws Exception {

    }

    /**
     * http://localhost:8080/test/hello/11111?requestParam=123456789  现代方式
     *
     * @param model
     * @param requestParam
     * @param pathVariable
     * @return
     */
    @RequestMapping(value = "hello/{pathVariable}", method = RequestMethod.GET)
    public String hello(Model model, @RequestParam Integer requestParam, @PathVariable Integer pathVariable) {
        System.out.println("courseId" + requestParam);
        System.out.println("courseId" + pathVariable);
        Course course = testService.getCoursebyId(11);
        model.addAttribute(course);
        logger.error("执行成功！");
        return "hello";
    }

    /**
     * 传统方式（不推荐使用）
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "course", method = RequestMethod.GET)
    @ResponseBody
    public Course hello(HttpServletRequest request) {
        String requestParam = request.getParameter("requestParam");
        System.out.println("courseId" + requestParam);
        Course course = testService.getCoursebyId(11);
        request.setAttribute("course", course);
        logger.error("执行成功！");
        return course;
    }

    /**
     * 带参数请求
     *
     * @return
     */
    @RequestMapping(value = "/admin", method = RequestMethod.GET, params = "add")
    public String createCourse() {
        return "course_admin/edit";
    }

    /**
     * 重定向
     *
     * @param course
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String doSave(@ModelAttribute Course course/*@SessionAttributes)*/, @CookieValue String cookieValue) {

        logger.debug("Info of Course:");
        logger.debug(ReflectionToStringBuilder.toString(course));

        //在此进行业务操作，比如数据库持久化
        course.setCourseId(123);
        //重定向(内部调整用forward)
        return "redirect:course?requestParam=" + course.getCourseId();
    }

    /**
     * 单文件上传
     *
     * @param multi
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.GET)
    public String showUploadPage(@RequestParam(value = "multi", required = false) Boolean multi) {
        if (multi != null && multi) {
            return "course_admin/multifile";
        }
        return "course_admin/file";
    }

    /**
     * 单文件上传
     *
     * @param file
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/doUpload", method = RequestMethod.POST)
    @ResponseBody
    public String doUploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException, NotFoundException {
        String path = request.getSession().getServletContext().getRealPath("/") + "resources/image/";
        if (!file.isEmpty()) {
            logger.debug("Process file: {}", file.getOriginalFilename());
            //解析二维码功能
            MultiFormatReader multiFormatReader = new MultiFormatReader();
            BufferedImage twoDimensionCode = ImageIO.read(file.getInputStream());
            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(twoDimensionCode)));
            Result result = multiFormatReader.decode(binaryBitmap);
            System.out.printf(result.toString() + result.getBarcodeFormat() + result.getText());
            //为图片打水印
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            System.out.printf(width + "-" + height);
            Graphics2D graphics2D = bufferedImage.createGraphics();
            graphics2D.drawImage(bufferedImage, 20, 20, 200, 80, null);
            graphics2D.dispose();//释放
            //上传到指定目录
            FileUtils.copyInputStreamToFile(file.getInputStream(), new java.io.File(path, System.currentTimeMillis() + file.getOriginalFilename()));
         /*   JPEGImageEncoder jpegImageEncoder = JPEGCodec.createJPEGEncoder(response.getOutputStream());
            jpegImageEncoder.encode(bufferedImage);*/
            IOUtils.closeQuietly(response.getOutputStream());
        }
        //生成缩略图
        Thumbnails.of(file.getInputStream()).size(1000, 1000).toFile(path + System.currentTimeMillis() + file.getOriginalFilename());
        IOUtils.closeQuietly(file.getInputStream());
        return null;
    }

    /**
     * 多文件上传
     *
     * @param multiRequest
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/doUpload2", method = RequestMethod.POST)
    public String doUploadFile2(MultipartHttpServletRequest multiRequest) throws IOException {

        Iterator<String> filesNames = multiRequest.getFileNames();
        while (filesNames.hasNext()) {
            String fileName = filesNames.next();
            MultipartFile file = multiRequest.getFile(fileName);
            if (!file.isEmpty()) {
                logger.debug("Process file: {}", file.getOriginalFilename());
                FileUtils.copyInputStreamToFile(file.getInputStream(), new java.io.File("F:\\", System.currentTimeMillis() + file.getOriginalFilename()));
            }

        }

        return null;
    }

    /**
     * 传统方式json（不推荐使用）
     *
     * @param courseId
     * @return
     */
    @RequestMapping(value = "/jsontype/{courseId}", method = RequestMethod.GET)
    public ResponseEntity<Course> getCourseInJson2(@PathVariable Integer courseId) {
        Course course = testService.getCoursebyId(courseId);
        return new ResponseEntity<Course>(course, HttpStatus.OK);
    }

    /**
     * 测试dao
     *
     * @param request
     */
    @RequestMapping(value = "test", method = RequestMethod.GET)
    @ResponseBody
    public List test(HttpServletRequest request) {
        List<User> list = testService.list();
        System.out.printf("");
        return list;
    }

    /**
     * 测试redis
     *
     * @param request
     */
    @RequestMapping(value = "redis")
    @ResponseBody
    public void redis(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Hibernate hibernate = new Hibernate();
        hibernate.setId(123);
        hibernate.setAddress("sjdhfjkdh");
        Map m = BeanUtils.describe(hibernate);
        template.opsForHash().putAll("userId", m);
        Map ss = template.opsForHash().entries("userId");

    }

    /**
     * 测试登陆
     */
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public String login(HttpServletRequest httpServletRequest, String userName, HttpServletResponse httpServletResponse) {
        String userCaptchaResponse = httpServletRequest.getParameter("jcaptcha");

   /*     boolean captchaPassed = SimpleImageCaptchaServlet.validateResponse(httpServletRequest, userCaptchaResponse);
        if(captchaPassed){
// proceed to submit action
        }else{
// return error to user
        }*/
        //存入session
        httpServletRequest.getSession().setAttribute("userName", httpServletRequest.getParameter("userName"));
        //将用户存入缓存
        template.opsForValue().set(httpServletRequest.getParameter("userName"), httpServletRequest.getParameter("userName"));
        //获取缓存数据
        System.out.printf(template.opsForValue().get(httpServletRequest.getParameter("userName")));
        return "hello";
    }

    /**
     * 测试生成二维码
     */
    @RequestMapping(value = "twoDimensionCode")
    public void twoDimensionCode(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws WriterException, IOException {
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        BitMatrix bitMatrix = new MultiFormatWriter().encode("www.imooc.com", BarcodeFormat.QR_CODE, 200, 200,hints);
        BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
        ImageIO.write(bufferedImage, "png", httpServletResponse.getOutputStream());
        IOUtils.closeQuietly(httpServletResponse.getOutputStream());
    }

    /**
     * 读取和修改配置文件
     */
    @RequestMapping(value = "property")
    public void property(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
        Properties props = PropertiesLoaderUtils.loadAllProperties("/property/common-message.properties");
        props.setProperty("banner.recommend", "true");
        props.store(new FileOutputStream(httpServletRequest.getSession().getServletContext().getRealPath("/") + "WEB-INF/classes/property/common-message.properties"), "");

    }

    /**
     * 手动生成验证码
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "verificationCode")
    public void verificationCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        BufferedImage bi = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.getGraphics();
        Color c = new Color(200, 150, 255);
        g.setColor(c);
        g.fillRect(0, 0, 68, 22);
        String randomAlphanumeric = RandomStringUtils.randomAlphanumeric(4);
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            Font font = new Font("楷体", Font.BOLD, 20);
            g.setFont(font);
            g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));
            g.drawString(randomAlphanumeric.charAt(i) + "", (i * 15) + 3, 18);
            g.drawLine(r.nextInt(80), r.nextInt(40), r.nextInt(80), r.nextInt(40));
            g.drawLine(r.nextInt(80), r.nextInt(40), r.nextInt(80), r.nextInt(40));
        }
        request.getSession().setAttribute("piccode", randomAlphanumeric.toString());
        ImageIO.write(bi, "JPG", response.getOutputStream());
        IOUtils.closeQuietly(response.getOutputStream());
    }

    /**
     * 验证码验证基于组件
     */
    @RequestMapping(value = "validCode")
    public void validCode(HttpServletRequest httpServletRequest) {
        String k = (String) httpServletRequest.getSession()
                .getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        String str = httpServletRequest.getParameter("r");
        if (k.equals(str))
            System.out.printf("true");
    }

    /**
     * 消息推送see
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "sse")
    public void sse(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/event-stream");
        PrintWriter writer = response.getWriter();
        for (int i = 0; i < 10; i++) {
            writer.write("data: " + System.currentTimeMillis() + "\n\n");
            IOUtils.closeQuietly(writer);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Bean
    public SystemWebSocketHandler systemWebSocketHandler() {
        return new SystemWebSocketHandler();
    }

    /**
     * 测试数据绑定
     *
     * @param request
     * @param appResult
     * @param bindingResult
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "auditing")
    @ResponseBody
    public AppResult auditing(HttpServletRequest request, AppResult appResult, BindingResult bindingResult) throws IOException {
        if (bindingResult.hasErrors()) {
            logger.error("数据绑定失败！");
        }
        //无关代码都省略了
        appResult.setResult(true);
        appResult.setMessage("sdfdf");
        systemWebSocketHandler().sendMessageToUsers(new TextMessage("sdfdf"));
        return appResult;
    }

    /**
     * 测试邮箱和velocity
     *
     * @param httpServletRequest
     * @throws GeneralSecurityException
     * @throws MessagingException
     */
    @RequestMapping("testMail")
    public void testMail(HttpServletRequest httpServletRequest) throws GeneralSecurityException, MessagingException {
        // 收件人电子邮箱
        String to = "1051477653@qq.com";
        // 发件人电子邮箱
        String from = "1051477653@qq.com";
        // 指定发送邮件的主机为 smtp.qq.com
        String host = "smtp.qq.com";  //QQ 邮件服务器
        // 获取系统属性
        Properties properties = System.getProperties();
        // 设置邮件服务器
        properties.setProperty("mail.smtp.host", host);

        properties.put("mail.smtp.auth", "true");
        // 获取默认session对象
        Session session = Session.getInstance(properties, new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("1051477653@qq.com", "wadpwrohigxhbdcd"); //发件人邮件用户名、密码
            }
        });


        // 创建默认的 MimeMessage 对象
        MimeMessage message = new MimeMessage(session);

        // Set From: 头部头字段
        message.setFrom(new InternetAddress(from));

        // Set To: 头部头字段
        message.addRecipient(Message.RecipientType.TO,
                new InternetAddress(to));

        // Set Subject: 头部头字段
        message.setSubject("这是一封测试邮件！");

        // 设置消息体
        String realPath = httpServletRequest.getSession().getServletContext().getRealPath("/");
        Properties p = new Properties();
        p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, realPath + "WEB-INF\\velocity");
        Velocity.init(p);
        VelocityContext context = new VelocityContext();
        StringWriter writer = new StringWriter();
        org.apache.velocity.Template template = Velocity.getTemplate("velocity.vm");
        template.merge(context, writer);
        String s = writer.toString();
        message.setContent(s,
                "text/html");

        // 发送消息
        Transport.send(message);
        System.out.println("Sent message successfully");
    }

    /**
     * 测试@valid
     */
    @RequestMapping("hibernateValid")
    public void hibernateValid(@Valid Hibernate hibernate, BindingResult result) {
        if (result.hasErrors()) {
            result.getFieldError().getDefaultMessage();//默认提示信息
            List<ObjectError> errorList = result.getAllErrors();
            for (ObjectError error : errorList) {
                System.out.println(error.getDefaultMessage());
            }
        }
    }

    /**
     * 测试csv
     */
    @RequestMapping("csv")
    public void csv(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException {
        httpServletResponse.setContentType("text/csv");
        httpServletResponse.setHeader("content-disposition", "attachment; filename=text.csv");
        CSVUtil.writeCsv(httpServletResponse.getWriter());
    }

    /**
     * 测试csv
     */
    @RequestMapping("jpa")
    public void jpa(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        testService.selectJpa();
    }

    /**
     * 上传图片
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public common.model.Result upload(HttpServletRequest httpServletRequest, MultipartFile file) throws IOException {
        HttpPost httppost = new HttpPost("http://localhost:8080/test/uploadFile");
        String BOUNDARY = "----------" + System.currentTimeMillis();
        httppost.addHeader("Content-Type", "multipart/form-data;boundary="
                + BOUNDARY);
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        multipartEntityBuilder.setBoundary(BOUNDARY);
        multipartEntityBuilder.addBinaryBody("file", file.getInputStream(), ContentType.APPLICATION_OCTET_STREAM, file.getName());
        multipartEntityBuilder.addTextBody("secret", "1234");
        multipartEntityBuilder.addTextBody("servletPath", httpServletRequest.getServletPath());
        httppost.setEntity(multipartEntityBuilder.build());
        HttpResponse httpResponse = hc.execute(httppost);
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        if (statusCode == org.apache.http.HttpStatus.SC_OK) {
            HttpEntity httpEntity = httpResponse.getEntity();
        }

        return null;
    }

    @ResponseBody
    @RequestMapping(value = "uploadFile", method = RequestMethod.POST)
    public common.model.Result uploadFile(HttpServletRequest httpServletRequest, MultipartFile file, File m) throws IOException {

        return null;
    }
}
